package design.pattern.application;

import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

/**
 * @program JavaBase
 * @description: 观察者 + 中介者
 *  事件触发器的开发
 * @author: zhanglu
 * @create: 2020-05-23 19:50:00
 */
public class ObserverAndMediatorDemo {

    public static void main(String[] args) {
        //获得事件分发中心
        EventDispatch dispatch = EventDispatch.getEventDispatch();
        //接受乞丐对事件的处理
        dispatch.registerCustomer(new Beggar());
        //接受平民对事件的处理
        dispatch.registerCustomer(new Commoner());
        //接受贵族对事件的处理
        dispatch.registerCustomer(new Nobleman());
        //建立一个原子弹生产工厂
        ProductManager factory = new ProductManager();
        //制造一个产品
        System.out.println("=====模拟创建产品事件========");
        System.out.println("创建一个叫做小男孩的原子弹");
        Product p = factory.createProduct("小男孩原子弹");
        //修改一个产品
        System.out.println("\n=====模拟修改产品事件========");
        System.out.println("把小男孩原子弹修改为胖子号原子弹");
        factory.editProduct(p, "胖子号原子弹");
        //再克隆一个原子弹
        System.out.println("\n=====模拟克隆产品事件========");
        System.out.println("克隆胖子号原子弹");
        factory.clone(p);
        //遗弃一个产品
        System.out.println("\n=====模拟销毁产品事件========");
        System.out.println("遗弃胖子号原子弹");
        factory.abandonProduct(p);
    }

}
//产品类
class Product implements Cloneable{
    //产品名称
    private String name;
    //是否可以属性变更
    private boolean canChanged = false;
    //产生一个新的产品
    public Product(ProductManager manager,String _name){
        //允许建立产品
        if(manager.isCreateProduct()){
            canChanged = true;
            this.name = _name;
        }
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        if(canChanged){
            this.name = name;
        }
    }

    //覆写clone方法 @Override
    public Product clone() {
        Product p = null;
        try {
            p = (Product) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}
//工厂类
class ProductManager {
    //是否可以创建一个产品
    private boolean isPermittedCreate = false;
    //建立一个产品
    public Product createProduct(String name){
        //首先修改权限，允许创建
        isPermittedCreate = true;
        Product p = new Product(this,name);
        //产生一个创建事件
        new ProductEvent(p,ProductEventType.NEW_PRODUCT); return p;
    }
    //废弃一个产品
    public void abandonProduct(Product p){
        //销毁一个产品，例如删除数据库记录
        //产生删除事件
        new ProductEvent(p,ProductEventType.DEL_PRODUCT); p = null;
    }
    //修改一个产品
    public void editProduct(Product p,String name){
        //修改后的产品
        p.setName(name);
        //产生修改事件
        new ProductEvent(p,ProductEventType.EDIT_PRODUCT);
    }
    //获得是否可以创建一个产品
    public boolean isCreateProduct(){
        return isPermittedCreate;
    }
    //克隆一个产品
    public Product clone(Product p){
        //产生克隆事件
        new ProductEvent(p,ProductEventType.CLONE_PRODUCT);
        return p.clone();
    }
}
//事件类型定义
enum ProductEventType {
    //新建一个产品
    NEW_PRODUCT(1),
    //删除一个产品
    DEL_PRODUCT(2),
    //修改一个产品
    EDIT_PRODUCT(3),
    //克隆一个产品
    CLONE_PRODUCT(4);
    private int value=0;
    private ProductEventType(int _value){
        this.value = _value;
    }
    public int getValue(){
        return this.value;
    }
}
//产品事件
class ProductEvent extends Observable { //事件起源
    private Product source; //事件的类型
    private ProductEventType type;

    //传入事件的源头，默认为新建类型
    public ProductEvent(Product p) {
        this(p, ProductEventType.NEW_PRODUCT);
    }

    //事件源头以及事件类型
    public ProductEvent(Product p, ProductEventType _type) {
        this.source = p;
        this.type = _type;
        //事件触发
        notifyEventDispatch();
    }

    //获得事件的始作俑者
    public Product getSource() {
        return source;
    }

    //获得事件的类型
    public ProductEventType getEventType() {
        return this.type;
    }
    private void notifyEventDispatch () {
        super.addObserver(EventDispatch.getEventDispatch());
        super.setChanged();
        super.notifyObservers(source);
    }
}
//事件的观察者
class EventDispatch implements Observer {
    //单例模式
    private final static EventDispatch dispatch = new EventDispatch();
    //事件消费者
    private Vector<EventCustomer> customer = new Vector<EventCustomer>();
    //不允许生成新的实例
    private EventDispatch(){
    }
    //获得单例对象
    public static EventDispatch getEventDispatch(){
        return dispatch;
    }
    //事件触发
    public void update(Observable o, Object arg) {
        //事件的源头
        Product product = (Product)arg;
        //事件
        ProductEvent event = (ProductEvent)o;
        //处理者处理，这里是中介者模式的核心，可以是很复杂的业务逻辑
        for(EventCustomer e: customer) {
            //处理能力是否匹配
            for (EventCustomType t : e.getCustomType()) {
                if (t.getValue() == event.getEventType().getValue()) {
                    e.exec(event);
                }
            }
        }
    }
    //注册事件处理者
    public void registerCustomer(EventCustomer _customer){ customer.add(_customer);
    }
}
//抽象的事件处理者
abstract class EventCustomer {
    //容纳每个消费者能够处理的级别
    private Vector<EventCustomType> customType = new Vector<EventCustomType>(); //每个消费者都要声明自己处理哪一类别的事件
    public EventCustomer(EventCustomType _type){
        addCustomType(_type);
    }
    //每个消费者可以消费多个事件
    public void addCustomType(EventCustomType _type){
        customType.add(_type);
    }
    //得到自己的处理能力
    public Vector<EventCustomType> getCustomType(){
        return customType;
    }
    //每个事件都要对事件进行声明式消费
    public abstract void exec(ProductEvent event);
}
//事件处理枚举
enum EventCustomType {
    //新建立事件
    NEW(1),
    //删除事件
    DEL(2),
    //修改事件
    EDIT(3),
    //克隆事件
    CLONE(4);
    private int value=0;
    private EventCustomType(int _value){
        this.value = _value;
    }
    public int getValue(){
        return value;
    }
}
//乞丐
class Beggar extends EventCustomer {
    //只能处理被人遗弃的东西
    public Beggar(){ super(EventCustomType.DEL);
    }
    @Override
    public void exec(ProductEvent event) {
        //事件的源头
        Product p = event.getSource();
        //事件类型
        ProductEventType type = event.getEventType();
        System.out.println("乞丐处理事件:"+p.getName() +"销毁,事件类型="+type);
    }
}
//平民
class Commoner extends EventCustomer {
    //定义平民能够处理的事件的级别
    public Commoner() {
        super(EventCustomType.NEW);
    }
    @Override
    public void exec(ProductEvent event) {
        //事件的源头
        Product p = event.getSource();
        //事件类型
        ProductEventType type = event.getEventType();
        System.out.println("平民处理事件:"+p.getName() +"诞生记,事件类型="+type);
    }
}
class Nobleman extends EventCustomer { //定义贵族能够处理的事件的级别
    public Nobleman() {
        super(EventCustomType.EDIT); super.addCustomType(EventCustomType.CLONE);
    }
    @Override
    public void exec(ProductEvent event) {
        //事件的源头
        Product p = event.getSource();
        //事件类型
        ProductEventType type = event.getEventType();
        if(type.getValue() == EventCustomType.CLONE.getValue()){
            System.out.println("贵族处理事件:"+p.getName() +"克隆,事件类型="+type);
        }else{
            System.out.println("贵族处理事件:"+p.getName() +"修改,事件类型="+type);
        }
    }
}

